package net.aiion.weave.impl.resources.url;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.StringTokenizer;

import net.aiion.weave.spi.resources.ResourceException;
import net.aiion.weave.spi.resources.url.URLConverter;
import net.aiion.weave.spi.resources.url.URLProvider;

public class SystemClasspathURLProvider implements URLProvider
{
    private URLConverter urlConverter;

    public SystemClasspathURLProvider() {
    }

    @Override
    public void setURLConverter(final URLConverter aURLConverter) {
        urlConverter = aURLConverter;
    }

    @Override
    public URLConverter getURLConverter() {
        return urlConverter;
    }

    @Override
    public Iterator<URL> iterator() {
        return loadSystemClasspathURLs().iterator();
    }

    private Collection<URL> loadSystemClasspathURLs() {
        final Collection<URL> systemClasspathURLs = new ArrayList<>();
        final StringTokenizer stringTokenizer = new StringTokenizer(System.getProperty("java.class.path"),
            File.pathSeparator);
        while (stringTokenizer.hasMoreTokens()) {
            try {
                final URL systemClasspathURL = loadSystemClasspathURL(URLDecoder.decode(stringTokenizer.nextToken(),
                    "UTF-8"));
                if (systemClasspathURL != null) {
                    systemClasspathURLs.add(systemClasspathURL);
                }
            } catch (final UnsupportedEncodingException e) {
                throw new ResourceException(e);
            }

        }

        return Collections.unmodifiableCollection(systemClasspathURLs);
    }

    private URL loadSystemClasspathURL(final String aEncodedURLPath) {
        final File f = new File(aEncodedURLPath);
        if (!f.exists()) {
            return null;
        }

        try {
            return convertURL(f.toURI().toURL());
        } catch (final MalformedURLException e) {
            throw new ResourceException(e);
        }
    }

    private URL convertURL(final URL aURL) throws MalformedURLException {
        if (urlConverter == null) {
            return aURL;
        }

        return urlConverter.convertURL(aURL);
    }
}
